<?
/**
 * 购物车类
 */


class Cart extends MyBase{
	
	function __construct() {
		parent::__construct('cart');
	}
	
	// 加入购物车
	public function add_to_cart($userid, $post){
		$goodsid = intval($post['goodsid']);
		$number = intval($post['number']);
		if($goodsid <= 0 || $number <= 0){
			return $this->rwarn('');
		}
		
		// 验证规格并计算价格、库存
		$oGoods = & Goods::instance();
		$goods = $oGoods->get_row($goodsid, '`price`,`quantity`,`quantityunit`');
		// 读取规格
		$specs = $oGoods->get_specs($goodsid, true);
		$specs = $specs['specs'];
		if(!empty($specs)){
			if(empty($post['specs'])){
				return $this->rwarn('未选择商品的规格');
			}
		}
		if(empty($post['specs'])){
			$post['specs'] = array();
		}
		
		if(empty($post['specs'])){	// 如果没有规格，则直接采用商品表的价格和数量
			$price = $goods['price'];
			$quantity = $goods['quantity'];
		}else{
			$errmsg = array();
			$price = 0; // 初始为商品的价格
			$quantity_arr = array();
			foreach($post['specs'] as $prototypeid => $key){
				if(empty($key)){
					$errmsg[] = '未选择：'.$specs[$prototypeid]['name'];
					continue;
				}
				if(!isset($specs[$prototypeid]) || !isset($specs[$prototypeid]['value'])){
					$errmsg[] = '规格不存在：'.$specs[$prototypeid]['name'];
				}
				if(is_array($specs[$prototypeid]['value'])){
					if(!isset($specs[$prototypeid]['value'][$key])){
						$errmsg[] = '规格不存在：'.$specs[$prototypeid]['name'];
					}
					$price_spec = floatval($specs[$prototypeid]['value'][$key]['price']);
					if($price_spec > $price){
						$price = $price_spec;
					}
					// 库存数量
					if(empty($specs[$prototypeid]['value'][$key]['autofill'])){
						$quantity_arr[$prototypeid] = intval($specs[$prototypeid]['value'][$key]['quantity']);
					}else{
						$quantity_arr[$prototypeid] = $goods['quantity'];
					}
				}else{
					$price_spec = floatval($specs[$prototypeid]['price']);
					if($price_spec > $price){
						$price = $price_spec;
					}
					// 库存数量
					if(empty($specs[$prototypeid]['autofill'])){
						$quantity_arr[$prototypeid] = intval($specs[$prototypeid]['quantity']);
					}else{
						$quantity_arr[$prototypeid] = $goods['quantity'];
					}
				}
			}
			if(!empty($errmsg)){
				return $this->rwarn(implode('<br />', $errmsg));	// 规格参数出错
			}
			if(empty($price)){
				$price = floatval($goods['price']); // 如果没有规格价格，则采用商品默认价格
			}
			rsort($quantity_arr);
			$quantity = array_pop($quantity_arr);
		}
		if($quantity < $post['number']){
			return $this->rwarn('库存不够，库存'.$quantity.Statics::$goods_quantity_unit_arr[$goods['quantityunit']]);	// 规格参数出错 
		}
		
		// 检查是否有相同规格的相同商品
		$select = array('userid' => $userid, 'goodsid' => $goodsid);
		$carts = $this->get_all('*', $select);
		if(!empty($carts['list'])){
			foreach($carts['list'] as $row){
				if($price == $row['price']){	// 价格须相同
					$diff1 = array_diff_assoc($row['specs'], $post['specs']);
					$diff2 = array_diff_assoc($post['specs'], $row['specs']);
					if(empty($diff1) && empty($diff2)){
						$data = array(
							'number'	=> $row['number'] + $number,
							'time'		=> TIME,
							'cost'		=> $row['cost'] + $price * $number,
						);
						$r = $this->db->update($this->tbname, $select, $data);
						return $this->rjust($r, $data);
					}
				}
				
			}
		}
		
		$fspecs = $this->format_specs($post['specs']);
		$data = array(
			'userid'	=> $userid,
			'goodsid'	=> $goodsid,
			'price'		=> $price,
			'number'	=> $number,
			'specs'		=> serialize($post['specs']),
			'fspecs'	=> serialize($fspecs),
			'time'		=> TIME,
			'cost'		=> $price * $number,
		);
		$orderid = $this->db->insert($this->tbname, $data);
		return $this->rjust($orderid);
	}
	
	public function update_cart($userid, $numbers){
		$iRtn = 0;
		foreach($numbers as $id => $number){
			$row = $this->get_row($id, '*');
			if(empty($row)){
				continue;
			}
			$data = array(
				'number'	=> $number,
				'cost'		=> $row['price'] * $number,
				'time'		=> TIME,
			);
			if($this->db->update($this->tbname, array('userid' => $userid, 'id' => $id), $data)){
				$iRtn ++;
			}
		}
		return $iRtn;
	}

	public function delete_from_cart($userid, $ids){
		if(!is_array($ids)){$ids = array($ids);}
		$iRtn = 0;
		foreach($ids as $id){
			if($this->db->delete($this->tbname, array('userid' => $userid, 'id' => $id), $limit = true)){
				$iRtn++;
			}
		}
		return $iRtn;
	}
	
	public function clear_cart($userid){
		return $this->db->delete($this->tbname, array('userid' => $userid), $limit = false);
	}
	
	/**
	 * 取一条记录
	 */
	public function get_row($id, $fields = '*'){
		return $this->db->get_row($this->tbname, array('id' => $id), $fields);
	}
	
	/**
	 * 取列表
	 */
	public function get_list($fields = '*', $select = array(), $order = array(), $page = 1, $size = 10, $offset = PAGE_OFFSET){
		$list = $this->db->get_list($this->tbname, $fields, $select, $order, $page, $size, $offset);
		if(!empty($list['list'])){
			$oGoods = & Goods::instance();
			foreach($list['list'] as $key => $row){
				$goods = $oGoods->get_row($row['goodsid'], '`name` as `goods_name`,`weight`,`weightunit`,`cover`,`filename`,`addtime`');
				$row = array_merge($row, $goods);
				if(!empty($row['specs'])){
					$row['specs'] = unserialize($row['specs']);
					if(empty($row['fspecs'])){
						$row['fspecs'] = $this->format_specs($row['specs']);
					}else{
						$row['fspecs'] = unserialize($row['fspecs']);
					}
				}
				$row['fweight'] = format_weight_out($row['weight'], $row['weightunit']);
				$row['ftime'] = ftime($row['time']);
				$list['list'][$key] = $row;
			}
		}
		return $list;
	}
	
	public function get_all($fields = '*', $select = array(), $order = array()){
		if(!isset($select['userid'])){
			return array();
		}
		$list = $this->db->get_all($this->tbname, $fields, $select, $order);
		if(!empty($list['list'])){
			$list['cost'] = 0;	// 总价
			$list['weight'] = 0;	// 总重量
			$oGoods = & Goods::instance();
			foreach($list['list'] as $key => $row){
				$list['cost'] += $row['cost'];
				$goods = $oGoods->get_row($row['goodsid'], '`name` as `goods_name`,`weight`,`weightunit`,`cover`,`filename`,`addtime`');
				$row = array_merge($row, $goods);
				$list['weight'] += $row['weight'] * $row['number'];
				if(!empty($row['specs'])){
					$row['specs'] = unserialize($row['specs']);
					if(empty($row['fspecs'])){
						$row['fspecs'] = $this->format_specs($row['specs']);
					}else{
						$row['fspecs'] = unserialize($row['fspecs']);
					}
				}
				$row['fweight'] = format_weight_out($row['weight'], $row['weightunit']);
				$row['ftime'] = ftime($row['time']);
				$list['list'][$key] = $row;
			}
		}
		
		return $list;
	}
	
	public function get_cart_num($userid = 0){
		return $this->db->get_counts($this->tbname, array('userid' => $userid));	
	}
	
	public function format_specs($specs){
		$prototypes = Prototype::get_prototypes();
		foreach($specs as $prototypeid => $name){
			if(is_array($prototypes[$prototypeid]['value'])){
				$specs[$prototypeid] = array(
					'name'	=> $prototypes[$prototypeid]['name'],
					'value'	=> $prototypes[$prototypeid]['value'][$name],
				);
			}else{
				$specs[$prototypeid] = array(
					'name'	=> $prototypes[$prototypeid]['name'],
					'value'	=> $prototypes[$prototypeid]['value'],
				);
			}
		}
		return $specs;
	}
	
	/***************************************************************************
	 * 计算总价
	 ***************************************************************************/
	
	public function cal_amount($userid, $payment = '', $delivery = ''){
		$cartlist = $this->get_all('*', array('userid' => $userid));
		if(empty($cartlist)){
			return null;
		}
		// 统计数组
		$amount = array(
			'cartlist'		=> $cartlist['list'],	// 
			'goods_cost'	=> $cartlist['cost'],	// 商品总价
			'cost'			=> $cartlist['cost'],	// 总价
			'weight'		=> format_weight_out($cartlist['weight'], 'kg'),
			'delivery_fee'	=> 0,	// 配送费用
			'payment_fee'	=> 0,	// 支付方式手续费
		);

		// 配送方式费用
		if(!empty($delivery)){
			$delivery_fee = $this->cal_delivery_fee($amount, $delivery);
			$amount = array_update($amount, $delivery_fee);
		}

		// 支付方式手续费
		if(!empty($payment)){
			$payment_fee = $this->cal_payment_fee($amount, $payment);
			$amount = array_update($amount, $payment_fee);
		}
		return $amount;
	}
	
	public function cal_delivery_fee($amount, $delivery){
		$deliverys = cache_read('deliverys.php');
		$delivery_info = $deliverys[$delivery];
		if(empty($delivery_info['feemod'])){	// 固定
			if($delivery_info['freeWeight'] > 0 && $amount['weight'] < $delivery_info['freeWeight']){
				$amount['delivery_fee'] = 0;
			}else{
				$amount['delivery_fee'] = $delivery_info['fee'];
				if($delivery_info['firstWeight'] > 0 && $amount['weight'] > $delivery_info['firstWeight']){
					if($delivery_info['followWeight'] > 0 && $delivery_info['followFee'] > 0){
						$amount['delivery_follow_fee'] = round(($delivery_info['followFee'] * (($amount['weight'] - $delivery_info['firstWeight']) / $delivery_info['followWeight'])), 2);
						$amount['delivery_fee'] += $amount['delivery_follow_fee'];
					}				
				}
			}		
		}else{
			// 自定义，即使用配送方式提供的计算方法进行计算
			$delivery_files = cache_read('delivery_files.php');
			$delivery_config = $delivery_files[$delivery];
			$config_file = APP_PTH.$delivery_config['path'].'_config.php';
			if(file_exists($config_file)){
				$clsname = 'Config_'.$delivery;
				include_once $config_file;
				if(class_exists($clsname, false)){
					$fee_cal_method = $delivery_info['feemod'];
					if(in_array($fee_cal_method, get_class_methods($clsname))){
						$amount['delivery_fee'] = call_user_func_array(array($clsname, $fee_cal_method), array($amount['weight']));
					}
				}
			}
			
		}
		$amount['cost'] += $amount['delivery_fee'];
		return $amount;
	}
	
	
	public function cal_payment_fee($amount, $payment){
		$payments = cache_read('payments.php');
		$payment_info = $payments[$payment];
		if(empty($payment_info['feemod'])){
			if(empty($payment_info['feeunit'])){	// 固定
				$amount['payment_fee'] = $payment_info['fee'];
			}elseif($payment_info['feeunit'] == '%'){	// 百分比
				// if(empty($payment_info['cod'])){
					$cost = $amount['cost'];
				// }else{
				// 	$cost = $amount['goods_cost'];	// 货到付款
				// }
				$amount['payment_fee'] = round(($cost * $payment_info['fee'] / 100), 2);
			}
		}else{	// 自定义，即使用支付方式提供的计算方法进行计算
			$payment_files = cache_read('payment_files.php');
			$payment_config = $payment_files[$payment];
			$config_file = APP_PTH.$payment_config['path'].'_config.php';
			if(file_exists($config_file)){
				$clsname = 'Config_'.$payment;
				include_once $config_file;
				if(class_exists($clsname, false)){
					$fee_cal_method = $payment_info['feemod'];
					if(in_array($fee_cal_method, get_class_methods($clsname))){
						$amount['payment_fee'] = call_user_func_array(array($clsname, $fee_cal_method), array($amount['cost']));
					}
				}
			}
		}
		$amount['cost'] += $amount['payment_fee'];
		return $amount;
	}
		
}
?>